package com.hanwei.uap.acceptors.sstn.service;

import com.hanwei.uap.common.data.check.CRC16;
import com.hanwei.uap.common.util.ByteUtil;
import com.hanwei.uap.common.util.DateUtil;
import com.hanwei.uap.acceptors.api.constants.ChannelKey;
import com.hanwei.uap.acceptors.api.service.TimeSynchronizeService;
import com.hanwei.uap.acceptors.api.utils.ChannelUtils;
import com.hanwei.uap.common.util.bytes.SstnUtil;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.util.Calendar;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Service
public class TimeSynchronizeServiceImpl implements TimeSynchronizeService {
    private Logger log = LoggerFactory.getLogger("command");
    private Map<String, String> deviceTimeMap = new ConcurrentHashMap<String, String>();

    @Scheduled(cron = "0 1 0 * * ?")
    @Override
    public void batchAsyncTime() {
        deviceTimeMap.clear();
    }

    @Override
    public void singleSyncTime(Channel channel) {
        if (channel != null && channel.isWritable()) {
            String deviceId = ChannelUtils.getDeviceId(channel);
            String deviceFullId = ChannelUtils.getDeviceFullId(channel, ChannelKey.DEVICEFULLID);
            byte[] v = new byte[24];
            v[0] = 0x3a;
            byte[] d = ByteUtil.hex2byte(deviceFullId);
            v[1] = d[0];
            v[2] = d[1];
            v[3] = d[2];
            v[4] = d[3];
            v[5] = d[4];
            v[6] = d[5];
            v[7] = d[6];
            v[8] = d[7];
            v[9] = d[8];
            v[10] = d[9];
            v[11] = 0x11;
            v[12] = 0x01;
            v[13] = 0x30;
            v[14] = 0x00;
            Calendar calendar = Calendar.getInstance();
            int year = calendar.get(Calendar.YEAR);
            v[15] = (byte) (calendar.get(Calendar.SECOND) & 0xff);
            v[16] = (byte) (calendar.get(Calendar.MINUTE) & 0xff);
            v[17] = (byte) (calendar.get(Calendar.HOUR_OF_DAY) & 0xff);
            v[18] = (byte) (calendar.get(Calendar.DAY_OF_MONTH) & 0xff);
            v[19] = (byte) ((calendar.get(Calendar.MONTH) + 1) & 0xff);
            v[20] = (byte) ((year % 100) & 0xff);
            byte[] bytes = new byte[20];
            System.arraycopy(v, 1, bytes, 0, 20);
            int crc = CRC16.getCrc16(bytes);
            v[21] = (byte) (crc & 0xff);
            v[22] = (byte) ((crc >> 8) & 0xff);
            v[23] = 0x0D;
            byte[] b = SstnUtil.transfer(v);
            ByteBuf timeBuf = Unpooled.wrappedBuffer(b);
            try {
                Thread.sleep(2000);
                channel.writeAndFlush(timeBuf);
                String syncTime = DateUtil.formatDF19(calendar.getTime());
                deviceTimeMap.put(deviceId, syncTime);
                if (log.isInfoEnabled()){
                    log.info("ChannelId:{}, DeviceId:{}, Send SyncTime Command:{}", channel.id().asShortText(), deviceId, ByteUtil.byte2hex(b));
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
                log.warn("thread sleep exception!", e);
            }
        }
    }

    @Override
    public boolean canSyncTime(String deviceId) {
        return !deviceTimeMap.containsKey(deviceId);
    }
}
